using MeetingManagement.Domain.Common;
using MeetingManagement.Domain.Repositories;
using Microsoft.EntityFrameworkCore;

namespace MeetingManagement.Infrastructure.Repositories;

public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class, IAggregateRoot, IEntity
{
    private readonly MeetingManagementDbContext _dbContext;

    public GenericRepository(MeetingManagementDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public virtual TEntity Get(Guid id)
    {
        return _dbContext.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }

    public virtual Task<TEntity> GetAsync(Guid id)
    {
        return _dbContext.Set<TEntity>().SingleOrDefaultAsync(x => x.Id == id);
    }

    public virtual IQueryable<TEntity> Query()
    {
        return _dbContext.Set<TEntity>();
    }

    public async Task CreateAsync(TEntity aggregateRoot)
    {
        await _dbContext.Set<TEntity>().AddAsync(aggregateRoot);
        await _dbContext.SaveChangesAsync();
    }

    public async Task CreateRangeAsync(params TEntity[] aggregateRoots)
    {
        await _dbContext.Set<TEntity>().AddRangeAsync(aggregateRoots);
        await _dbContext.SaveChangesAsync();
    }

    public async Task UpdateAsync(TEntity aggregateRoot)
    {
        _dbContext.Set<TEntity>().Update(aggregateRoot);
        await _dbContext.SaveChangesAsync();
    }

    public async Task UpdateRangeAsync(params TEntity[] aggregateRoots)
    {
        _dbContext.Set<TEntity>().UpdateRange(aggregateRoots);
        await _dbContext.SaveChangesAsync();
    }

    public async Task DeleteAsync(TEntity aggregateRoot)
    {
        _dbContext.Set<TEntity>().Remove(aggregateRoot);
        await _dbContext.SaveChangesAsync();
    }
}
